#!/usr/bin/python3
#
# Copyright (C) 2012-2013 Gameloft
# nikolay.yakovlev@gameloft.com
# niko.yakovlev@yandex.ru
# vegasq@gmail.com
# 28.03.2013

import urllib
import urllib2
import logging
logging.basicConfig(filename='log.log',level=logging.DEBUG)

try:
    is_urllib2 = False
    import urllib.request
    urlopen = urllib.request.urlopen
    request = urllib.request.Request
    urlencode = urllib.parse.urlencode
except ImportError:
    is_urllib2 = True
    urlopen = urllib2.urlopen
    request = urllib2.Request
    urlencode = urllib.urlencode

import json
import sys
import requests

logging.basicConfig(filename='log.log',level=logging.DEBUG)

class FService:
    debug = True
    def __init__(self, url, credential, access_token, client_id):

        self.credential = credential
        self.access_token = access_token
        self.client_id = client_id
        self.url = url


class Hestia(FService):
    def get_clusters(self):
        retrieve_url = "%s/clusters?access_token=%s" % (self.url, self.access_token)
        return self.request(retrieve_url)

    def post(self, line, cluster_name='world'):
        retrieve_url = "%s/configs/clusters/%s/game/default?access_token=%s" % (self.url, cluster_name, self.access_token)
        retrieve_url = retrieve_url.replace(" ", '%20')
        retrieve_params = {
            'line' : line
        }
        self.request(retrieve_url, retrieve_params)


    def get(self, cluster_name='world'):
        retrieve_url = "%s/configs/clusters/%s/game/default?access_token=%s" % (self.url, cluster_name, self.access_token)
        return self.request(retrieve_url)

    def request(self, url, post = False):
        if post:
            print('POST:')
            print()
            print(url)
            # print(post)
            data = urlencode(post).encode('ascii')
            req = request(url, data)

            if is_urllib2:
                print('urllib2')
                try:
                    resp = urlopen( req )
                except urllib2.HTTPError, e:
                    print(e, e.read())
                    exit()
                    logging.debug(e.read(), data)
                    exit()
            else:
                print('urllib')
                try:
                    resp = urlopen( req )
                except urllib.HTTPError as e:
                    logging.debug(e.read(), data)
                    exit()


            try:
                resp = urlopen( req )
            except urllib.HTTPError as e:
                logging.debug(e.read(), data)
                exit()
        else:
            resp = requests.get(url)
            try:
                result = resp.text
            except AttributeError:
                result = resp.content



        if('text' in dir(resp)):
            return resp.text 
        else:
            return resp.readlines()[0].decode("utf-8")


class Iris(FService):
    def send(self, url, post = False, fl = False):
        if post:
            resp = requests.post(url,
                data=post,
                files={'data': open(fl, 'rb')})
            logging.debug(resp.content)
            try:
                return resp.text
            except AttributeError:
                return resp.content
        else:
            resp = urlopen( url )
            return resp.read()


    def upload(self, fl, key):
        retrieve_url = "%s/assets/%s/%s" % (self.url, self.client_id, key)
        retrieve_params = {
            'client_id' : self.client_id,
            'access_token' : self.access_token,
            'override' : "Mom, i'm in tv",
            'only_this_client':'true'
        }

        return self.send(retrieve_url, retrieve_params, fl)

    def get(self, key):
        retrieve_url = "%s/assets/%s/%s" % (self.url, self.client_id, key)
        return self.send(retrieve_url, False, key)


class Seshat(FService):

    def send(self, url, post = False):
        if post:

            data = urlencode(post).encode('ascii')
            req = request(url, data)
            try:
                resp = urlopen( req )
            except urllib.error.HTTPError as e:
                logging.debug(e.read(), data)
                exit()
        else:
            resp = requests.get(url)
            try:
                result = resp.text
            except AttributeError:
                result = resp.content

        try:
            logging.debug(result)
        except:
            pass
        try:
            logging.debug(resp, dir(resp), resp.content)
        except:
            pass

        return resp.readlines()[0].decode("utf-8")


    def get(self, key):
        retrieve_url = "%s/data/%s/%s" % (self.url, self.credential, key)
        retrieve_params = 'access_token=%s&key=%s&credential=%s' % (self.access_token, key, self.credential)

        return self.send("%s?%s" % (retrieve_url, retrieve_params))

    def set(self, key, val):
        retrieve_url = "%s/data/%s/%s" % (self.url, self.credential, key)
        retrieve_params = {
            'key' : key,
            'access_token' : self.access_token,
            'data' :  val,
            'visibility' : 'public',
            'credential' : self.credential,
        }

        return self.send(retrieve_url, retrieve_params)

    def delete(self, key):
        retrieve_url = "%s/data/%s/%s/delete" % (self.url, self.credential, key)
        retrieve_params = {
            'access_token' : self.access_token,
            'key' : key
        }

        return self.send(retrieve_url, retrieve_params)

class Federation:
    debug = True
    def __init__(self, client_id, username, password):
        self.username = username
        self.password = password
        self.init_settings()
        self.client_id = client_id
        logging.debug([self.client_id,])
        self.load_eve()
        self.load_janus()

    def init_settings(self):
#        self.client_id           = "1733:53659:0.0.1:ios:appstore"#"1701:53469:0.0.1:ios"
        self.eve_url             = "http://eve.gameloft.com:20001"
        # self.username            = "KakaoBlockBreakerSettingsMaster"
        # self.password            = "D4aXanUsaTrE"

    def get_token(self):
        return True

    def load_eve(self):
        url_to_open =  "%s/config/%s" % (self.eve_url, self.client_id) 
#        logging.debug("EVE loading... ", url_to_open)
#        print(url_to_open)
 #       exit()
        response = urlopen( url_to_open )
        eve_response = response.readlines()[0].decode("utf-8")
        self.eve_data = json.loads( eve_response )
        #if self.debug:
        #    json.dump( self.eve_data, sys.stdout, sort_keys=True, indent=4 )
        return self.eve_data

    def load_janus(self):
        self.pandora_url = self.eve_data["pandora"]
        response = urlopen( "%s/locate?service=auth" % (self.pandora_url) )
        self.janus_url = "https://" + response.readlines()[0].decode("utf-8")

        auth_url = "%s/authorize" % self.janus_url
        auth_params = {
            'client_id' : self.client_id,
            'username' : "game:%s" % self.username,
            'password' : self.password,
            'scope' : 'storage asset_upload'# config_structure config config_edit'
        }

        logging.debug('Janus requested:')
        logging.debug(auth_url)
        logging.debug(auth_params)

        data = urlencode(auth_params).encode('ascii')
        req = request(auth_url, data)
        try:
            auth = urlopen(req)
            self.auth_data = json.loads(auth.readlines()[0].decode("utf-8"))
        except urllib2.HTTPError as e:
            logging.debug(e.info)
            logging.debug(e.message)
            logging.debug(e.read())
            logging.debug(e.readlines())
            logging.debug(e.strerror)
            logging.debug(" . ".join(dir(e)))
            logging.debug("<<<<<")
#            exit('error')

        #self.auth_data = json.loads(auth.readlines()[0].decode("utf-8"))
        #if self.debug:
        #    json.dump(self.auth_data, sys.stdout, sort_keys=True, indent=4)
        return self.auth_data

    def load_seshat(self):
        pandora_seshat_response = urlopen( "%s/locate?service=storage" % (self.pandora_url) )
        self.seshat_url = "https://" + pandora_seshat_response.readlines()[0].decode("utf-8")
        return Seshat(self.seshat_url, 'game:%s' % self.username, self.auth_data['access_token'], self.client_id)

    def load_iris(self):
        pandora_response = urlopen( "%s/locate?service=asset" % (self.pandora_url) )
        self.iris_url = "https://" + pandora_response.readlines()[0].decode("utf-8")
        return Iris(self.iris_url, 'game:%s' % self.username, self.auth_data['access_token'], self.client_id)

    def load_hestia(self):
        pandora_response = urlopen( "%s/locate?service=config" % (self.pandora_url) )
        self.hestia_url = "https://" + pandora_response.readlines()[0].decode("utf-8")
        return Hestia(self.hestia_url, 'game:%s' % self.username, self.auth_data['access_token'], self.client_id)




# fed = Federation()
# seshat = fed.load_seshat()

# seshat.set('somekey1', 'some_incredible_value')
# k = seshat.get('BlockBreakerSettings')
# logging.debug(k)
